package cn.zebra.dev.mall.module.orders.controller;

import cn.zebra.dev.common.constant.ParamsConstant;
import cn.zebra.dev.common.restful.Result;
import cn.zebra.dev.common.utils.ObjectUtils;
import cn.zebra.dev.ibatis.plus.utils.PageUtils;
import cn.zebra.dev.mall.module.orders.dto.OrderItemDTO;
import cn.zebra.dev.mall.module.orders.dto.OrdersDTO;
import cn.zebra.dev.mall.module.orders.dto.OrdersListDTO;
import cn.zebra.dev.mall.module.orders.dto.OrdersListItemDTO;
import cn.zebra.dev.mall.module.orders.vo.OrdersListVO;
import cn.zebra.dev.mall.module.orders.vo.OrdersUpdateAddressVO;
import cn.zebra.dev.member.module.address.entity.MemberAddressEntity;
import cn.zebra.dev.member.module.address.service.MemberAddressService;
import cn.zebra.dev.member.module.login.service.SecurityMemberService;
import cn.zebra.dev.member.module.member.service.MemberService;
import cn.zebra.dev.order.module.express.entity.OrdersExpressEntity;
import cn.zebra.dev.order.module.express.service.OrdersExpressService;
import cn.zebra.dev.order.module.item.entity.OrdersItemEntity;
import cn.zebra.dev.order.module.item.service.OrdersItemService;
import cn.zebra.dev.order.module.order.constant.OrdersStatusConstant;
import cn.zebra.dev.order.module.order.entity.OrdersEntity;
import cn.zebra.dev.order.module.order.service.OrdersService;
import cn.zebra.dev.shop.module.shop.service.ShopService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

@Api(tags = "订单服务")
@RestController
@RequestMapping("/orders")
public class OrdersController {

    @Autowired
    private MemberService memberService;

    @Autowired
    private MemberAddressService memberAddressService;

    @Autowired
    private OrdersService ordersService;

    @Autowired
    private OrdersItemService ordersItemService;

    @Autowired
    private OrdersExpressService ordersExpressService;

    @Autowired
    private SecurityMemberService securityMemberService;

    @Autowired
    private ShopService shopService;


    @GetMapping("/list")
    @ApiOperation("订单列表")
    public Result<PageUtils<OrdersListDTO>> list(
            @Valid OrdersListVO params,
            @RequestParam(value = "limit", defaultValue = "10", required = false) Integer limit,
            @RequestParam(value = "page", defaultValue = "1", required = false) Integer page) {
        Map<String, Object> map = ObjectUtils.objectConvertMap(params);
        if (map.containsKey("ordersStatus")) {
            String ordersStatusStr = map.get("ordersStatus").toString();
            int ordersStatus = Integer.parseInt(ordersStatusStr);
            if (ordersStatus == 2) {
                map.remove("ordersStatus");
                List<Integer> statusList = new LinkedList<>();
                statusList.add(OrdersStatusConstant.PAYMENT_RECEIVED);
                statusList.add(OrdersStatusConstant.WAIT_SHIPPED);
                statusList.add(OrdersStatusConstant.SHIPPED);
                statusList.add(OrdersStatusConstant.CONDUCT);
                map.put("ordersStatusIn", statusList);
            }
        }
        map.put("notPayTime", true);
        map.put("notOrderTitle", true);
        map.put("notParentId", true);
        map.put("notTotalNum", true);
        map.put("notCancelTime", true);
        map.put("notFulfilTime", true);
        map.put("notOtherTime", true);
        map.put("ordersUserId", securityMemberService.getMemberId());
        map.put(ParamsConstant.LIMIT, limit);
        map.put(ParamsConstant.PAGE, page);
        PageUtils<OrdersEntity> pageUtils = ordersService.findPage(map);
        List<OrdersEntity> list = pageUtils.getList();
        PageUtils<OrdersListDTO> data = new PageUtils<>(pageUtils);
        if (list.size() > 0) {
            List<Long> ordersIds = list.stream().map(OrdersEntity::getId).collect(Collectors.toList());
            List<OrdersItemEntity> ordersItemEntities = ordersItemService.findByOrderIds(ordersIds);
            List<OrdersListDTO> dtoList = new LinkedList<>();
            list.forEach(orderEntity -> {
                OrdersListDTO orderDTO = new OrdersListDTO();
                Long ordersId = orderEntity.getId();
                orderDTO.setShopId(orderEntity.getShopId());
                orderDTO.setOrdersId(ordersId);
                orderDTO.setOrdersType(orderEntity.getOrdersType());
                orderDTO.setOrdersSn(orderEntity.getOrdersSn());
                orderDTO.setTotalPrice(orderEntity.getTotalPrice());
                orderDTO.setOrdersStatus(orderEntity.getOrdersStatus());
                orderDTO.setCreateTime(orderEntity.getCreateTime());
                List<OrdersListItemDTO> orderItemDtoList = new LinkedList<>();
                List<OrdersItemEntity> itemEntities = ordersItemEntities.stream().filter(ordersItemEntity -> ordersItemEntity.getOrdersId().equals(ordersId)).collect(Collectors.toList());
                itemEntities.forEach(ordersItemEntity -> {
                    OrdersListItemDTO itemDTO = new OrdersListItemDTO();
                    itemDTO.setProductId(ordersItemEntity.getProductId());
                    itemDTO.setProductName(ordersItemEntity.getProductName());
                    itemDTO.setProductImage(ordersItemEntity.getProductImage());
                    itemDTO.setProductAttributes(ordersItemEntity.getProductAttributes());
                    orderItemDtoList.add(itemDTO);
                });
                orderDTO.setItemList(orderItemDtoList);
                dtoList.add(orderDTO);
            });
            data.setList(dtoList);
        }
        return Result.success(data);
    }

    @GetMapping("/info/{id}")
    @ApiOperation("订单详情")
    public Result<OrdersDTO> info(@PathVariable Long id) {
        OrdersEntity entity = ordersService.findById(id);
        OrdersDTO dto = new OrdersDTO();
        BeanUtils.copyProperties(entity, dto);
        Long addressId = entity.getAddressId();
        if (addressId != 0) {
            MemberAddressEntity addressEntity = memberAddressService.findById(addressId);
            if (addressEntity != null) {
                dto.setAddressInfo(addressEntity.getAddressInfo());
                dto.setPhone(addressEntity.getPhone());
                dto.setRecipientName(addressEntity.getRecipientName());
            }
        }
        Integer ordersStatus = entity.getOrdersStatus();
        if (ordersStatus.equals(OrdersStatusConstant.SHIPPED) || ordersStatus.equals(OrdersStatusConstant.CONDUCT) || ordersStatus.equals(OrdersStatusConstant.WAIT_APPRAISE) || ordersStatus.equals(OrdersStatusConstant.FULFIL)) {
            OrdersExpressEntity expressEntity = ordersExpressService.findByOrdersId(id);
            dto.setExpressSn(expressEntity.getExpressSn());
        }
        Collection<OrdersItemEntity> itemEntities = ordersItemService.findByOrderId(id);
        List<OrderItemDTO> itemList = new LinkedList<>();
        itemEntities.forEach(itemEntity -> {
            OrderItemDTO itemDTO = new OrderItemDTO();
            BeanUtils.copyProperties(itemEntity, itemDTO);
            itemList.add(itemDTO);
        });
        dto.setItemList(itemList);
        return Result.success(dto);
    }

    @GetMapping("/cancel/{id}")
    @ApiOperation("取消订单")
    public Result cancel(@PathVariable Long id) {
        if (ordersService.cancel(id, securityMemberService.getMemberId())) {
            return Result.success("取消成功!");
        }
        return Result.error("取消失败");
    }

    @PostMapping("/updateAddress/{id}")
    @ApiOperation("修改订单地址 - 待付款时")
    public Result updateAddress(@Valid @PathVariable Long id, @RequestBody OrdersUpdateAddressVO vo) {

        Long addressId = vo.getAddressId();
        Long memberId = securityMemberService.getMemberId();
        MemberAddressEntity addressEntity = memberAddressService.findByIdAndMemberId(addressId, memberId);
        if (addressEntity == null) {
            return Result.error("地址异常!");
        }
        if (!ordersService.updateAddressIdByIdAndOrdersUserId(id, addressId, memberId)) {
            return Result.error("订单异常!");
        }
        return Result.success("修改成功！");
    }
}
